﻿#region Using namespaces

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;

#endregion

namespace BOL.Apps.GeneNetworkBrowser.ViewModels
{
    public class TreeViewItemViewModel : ViewModelBase
    {
        #region Private variables

        private static readonly TreeViewItemViewModel _dummyChild = new TreeViewItemViewModel();
        private readonly ObservableCollection<TreeViewItemViewModel> _children;
        private readonly TreeViewItemViewModel _parent;
        private bool _isSelected;
        private bool _isExpanded;
        private bool _isEditing;
        private ObservableCollection<CommandViewModel> _contextMenuItems;

        #endregion

        #region Public properties

        /// <summary>Returns the logical child items of this object.</summary>
        public ObservableCollection<TreeViewItemViewModel> Children { get { return _children; } }

        /// <summary>Returns true if this object's Children have not yet been populated.</summary>
        public bool HasDummyChild { get { return Children.Count == 1 && Children[0] == _dummyChild; } }

        /// <summary>
        /// Gets/sets whether the TreeViewItem associated with this object is selected.
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value != _isSelected)
                {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }
            }
        }

        /// <summary> Gets/sets whether the TreeViewItem associated with this object is expanded.</summary>
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    _isExpanded = value;
                    OnPropertyChanged("IsExpanded");
                }

                // Expand all the way up to the root.
                if (_isExpanded && _parent != null)
                    _parent.IsExpanded = true;

                // Lazy load the child items, if necessary.
                if (HasDummyChild)
                {
                    Children.Remove(_dummyChild);
                    LoadChildren();
                }
            }
        }

        public bool IsEditing
        {
            get { return _isEditing; }
            set
            {
                if (value != _isEditing)
                {
                    _isEditing = value;
                    OnPropertyChanged("IsEditing");
                }
            }
        }

        public ICommand SwitchToEditingMode { get; private set; }

        public override string Title
        {
            get { return _title; }
            set
            {
                if (value != _title)
                {
                    _title = value;
                    OnPropertyChanged("Title");
                    _isEditing = false;
                }
            }
        }

        public TreeViewItemViewModel Parent { get { return _parent; } }

        public ObservableCollection<CommandViewModel> ContextMenuItems { get { return _contextMenuItems; } }

        #endregion

        #region Constructors

        public TreeViewItemViewModel(TreeViewItemViewModel parent, bool lazyLoadChildren)
            : base()
        {
            _parent = parent;
            _children = new ObservableCollection<TreeViewItemViewModel>();

            if (lazyLoadChildren)
                _children.Add(_dummyChild);

            //SwitchToEditingMode = new RelayCommand(param => _isEditing = !_isEditing, param => _name != name);
            _contextMenuItems = new ObservableCollection<CommandViewModel>();
        }

        public TreeViewItemViewModel() : base() { }

        #endregion

        #region Protected methods

        /// <summary>
        /// Invoked when the child items need to be loaded on demand.
        /// Subclasses can override this to populate the Children collection.
        /// </summary>
        protected virtual void LoadChildren() { }

        public bool ContainsText(string text)
        {
            if (String.IsNullOrEmpty(text) || String.IsNullOrEmpty(_title))
                return false;

            return _title.IndexOf(text, StringComparison.InvariantCultureIgnoreCase) > -1;
        }

        protected void AddContextMenu(string name, string imagePath, ICommand command)
        {
            _contextMenuItems.Add(new MenuItemViewModel(name, imagePath, command));
        }

        protected void AddContextMenu(string name, ICommand command)
        {
            _contextMenuItems.Add(new MenuItemViewModel(name, command));
        }

        #endregion
    }
}
